package org.lookahead.parent.common.mvc;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 日志拦截器
 * <pre>
 *      输出一些header信息到MDC。增加uri和access token(or session id)
 *  </pre>
 *
 */
public class LogInterceptor implements HandlerInterceptor {

    public static final String NOT_FOUND_STRING = "-";
    final static String USER_AGENT_EXP = "([^/]+)/([^ ]+) \\(([^;]+); ([^;]+); (.*)\\)";
    final static Pattern USER_AGENT_PATTERN = Pattern.compile(USER_AGENT_EXP);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String uri = request.getRequestURI();
        MDC.put("uri", uri);

        String sessionId = UUID.randomUUID().toString().replaceAll("-", "");
        MDC.put("sessionId", sessionId);

        String deviceid = request.getHeader("deviceid");
        if (StringUtils.isBlank(deviceid)) {
            deviceid = NOT_FOUND_STRING;
        }
        MDC.put("deviceid", deviceid);

        String area = request.getHeader("area");
        if (StringUtils.isBlank(area)) {
            area = NOT_FOUND_STRING;
        }
        MDC.put("area", area);

        String uid = request.getHeader("uid");
        if (StringUtils.isBlank(uid)) {
            uid = NOT_FOUND_STRING;
        }
        MDC.put("uid", uid);


        //增加版本、设备信息
        String userAgent = request.getHeader("User-Agent");
        if (StringUtils.isNotBlank(userAgent)) {
            Matcher m = USER_AGENT_PATTERN.matcher(userAgent);
            String ipsVersion = NOT_FOUND_STRING;
            String osVersion = NOT_FOUND_STRING;
            String equipment = NOT_FOUND_STRING;
            if (m.find()) {
                ipsVersion = m.group(2);
                osVersion = m.group(4);
                equipment = m.group(3);
                if (StringUtils.isNotBlank(equipment)) {
                    if ("phone".equalsIgnoreCase(equipment) || "iPhone".equalsIgnoreCase(equipment)) {
                        equipment = "phone";
                    } else if ("pad".equalsIgnoreCase(equipment) || "iPad".equalsIgnoreCase(equipment)) {
                        equipment = "pad";
                    }
                }
            }
            MDC.put("ipsVersion", ipsVersion);
            MDC.put("osVersion", osVersion);
            MDC.put("equipment", equipment);
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}
